package com.chuchet.bluetooth.printer.flutter_bluetooth_printer;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

public class FlutterBluetoothPrinterPlugin implements FlutterPlugin, ActivityAware, MethodCallHandler {
    private MethodChannel channel;
    private Context context;
    private Activity activity;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        context = binding.getApplicationContext();
        channel = new MethodChannel(binding.getBinaryMessenger(), "flutter_bluetooth_printer");
        channel.setMethodCallHandler(this);
    }

    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
        activity = binding.getActivity();
    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
        onAttachedToActivity(binding);
    }

    @Override
    public void onDetachedFromActivity() {
        context = null;
        activity = null;
        channel = null;
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
        onDetachedFromActivity();
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if (call.method.equals("printerStart")) {
            BluetoothDevice device = getPrinterDevice();
            byte[] bytes = call.argument("data");
            if (device == null) {
                result.success(Map.of("code", -1, "msg", "未获取到蓝牙打印设备"));
            } else if (bytes == null) {
                result.success(Map.of("code", 0, "msg", "未获取到打印内容"));
            } else {
                connectPrinterDevice(device, bytes, result);
            }
        } else if (call.method.equals("printerOpenBluetooth")) {
            openBluetoothSetting();
        } else if (call.method.equals("printerOpenWifi")) {
            openWifiSetting();
        } else {
            result.notImplemented();
        }
    }

    private void connectPrinterDevice(BluetoothDevice device, byte[] bytes, @NonNull Result result) {
        new Thread(() -> {
            BluetoothSocket socket = null;
            try {
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                socket.connect();
                Thread.sleep(50);
                OutputStream outputStream = socket.getOutputStream();
                outputStream.write(bytes);
                outputStream.flush();
                result.success(Map.of("code", 1, "msg", "蓝牙打印设备连接成功"));
            } catch (IOException | InterruptedException e) {
                result.success(Map.of("code", 0, "msg", "蓝牙连接异常:" + e.getMessage()));
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException ignored) {

                    }
                }
            }
        }).start();
    }

    private BluetoothDevice getPrinterDevice() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        if (adapter == null || !adapter.isEnabled()) {
            return null;
        }
        Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
        for (BluetoothDevice device : bondedDevices) {
            if (device.getBluetoothClass().getMajorDeviceClass() == 1536) {
                return device;
            }
        }
        return null;
    }

    private void openBluetoothSetting() {
        Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
        activity.startActivity(intent);
    }

    private void openWifiSetting() {
        Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
        activity.startActivity(intent);
    }

    @Override

    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }
}
